/*
 * 系统名称: 
 * 模块名称: webpasser.core
 * 类 名 称: XmlPageParser.java
 *   
 */
package com.hxt.webpasser.parser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.hxt.webpasser.module.CrawlUrl;
import com.hxt.webpasser.module.LinkPageInfo;
import com.hxt.webpasser.module.PageResult;
import com.hxt.webpasser.parser.filter.LinkFilter;
import com.hxt.webpasser.regular.AcceptDecideRuleHandler;
import com.hxt.webpasser.spider.SpiderController;
import com.hxt.webpasser.spider.common.CrawlUrlUtil;
import com.hxt.webpasser.transport.xml.DigLink;
import com.hxt.webpasser.transport.xml.Field;
import com.hxt.webpasser.transport.xml.LinkPage;
import com.hxt.webpasser.transport.xml.Page;
import com.hxt.webpasser.transport.xml.Param;
import com.hxt.webpasser.transport.xml.Rule;
import com.hxt.webpasser.transport.xml.XmlTask;
import com.hxt.webpasser.utils.FillParamValueUtil;
import com.hxt.webpasser.utils.StringUtil;

/**
 * 功能说明:  <br>
 * 系统版本: v1.0 <br>
 * 开发人员: hanxuetong <br>
 * 开发时间: 2015-9-14 <br>
 * 审核人员:  <br>
 * 相关文档:  <br>
 * 修改记录:  <br>
 * 修改日期 修改人员 修改说明  <br>
 * ======== ====== ============================================ <br>
 * 
 */
public class XmlPageParser implements HtmlParser {

	private XmlTask xmlTask;
	private SpiderController spiderController;
	
	public XmlPageParser( XmlTask xmlTask,SpiderController spiderController)
	{
		
		this.xmlTask=xmlTask;
		this.spiderController=spiderController;
	}
	
	
	
	@SuppressWarnings("unchecked")
	public Set<String> extracLinks(PageResult pageResult, LinkFilter filter) {
		Set<String> urlSet=new HashSet<String>();
		 List<Page> xmlPages=xmlTask.getPages();
		 if(xmlPages!=null)
		 {
//			 Map valueMap=new HashMap<String,Object>();
//			 valueMap.put("fetchUrl", pageResult.getUrl());
//			 valueMap.put("taskName", xmlTask.getName()); //返回结果中默认有的字段值
			 Map<String,Object> returnValue=new HashMap<String, Object>();
			 returnValue.put("fetchUrl", pageResult.getUrl());
			 returnValue.put("taskName", xmlTask.getName()); //返回结果中默认有的字段值
			 if(!spiderController.getGlobalValuesMap().isEmpty()){ // 放入全局参数值
				 returnValue.putAll(spiderController.getGlobalValuesMap());	 
			 }
			 String content=pageResult.getContent();
			 
			 for(int i=0;i<xmlPages.size();i++)
			 {
				 Page xmlPage=xmlPages.get(i);
				 AcceptDecideRuleHandler acceptDecideRuleHandler=new AcceptDecideRuleHandler();
				 if(spiderController.getCustomLoadConfig().getCustomDecideRuleMap()!=null){ //自定义rule处理
					 acceptDecideRuleHandler.setCustomDecideRuleMap(spiderController.getCustomLoadConfig().getCustomDecideRuleMap());
				 }
				 List<Rule> scopeRules=xmlPage.getScope();
				 //满足条件
				 if(AcceptDecideRuleHandler.isAccept(scopeRules, pageResult.getUrl()))
				 {
					 
					 List<Field> fields = xmlPage.getFields();
					 /*
					 if(pageResult.getPersistentPageInt()==null&&fields!=null) //将对应page的name放入
					 {
						 pageResult.setPersistentPageInt(i);
					 }*/
					 handleReturnValue(fields, content, pageResult, returnValue, xmlPage);
					 
					 handleLinkPage(content, pageResult, returnValue, xmlPage, acceptDecideRuleHandler);
					 putParseDigLink(xmlPage.getDigLinks(), urlSet, acceptDecideRuleHandler, pageResult.getContent(),returnValue);
				 }
				 
			 }
			 pageResult.setReturnValue(returnValue);
		 }
		
		return urlSet;
	}
	
	
	/**
	 * 处理返回内容值
	 * @param fields
	 * @param content
	 * @param pageResult
	 * @param returnValue
	 */
	private void handleReturnValue(List<Field> fields,String content, PageResult pageResult,Map<String,Object> returnValue,Page xmlPage){
		
		if(pageResult.getLinkParamValueMap()!=null&&xmlPage.getName().equals(pageResult.getLinkPageName()))
		{
			//从其他网页关联过来的赋值
			for(Map.Entry<String,Object> entry:pageResult.getLinkParamValueMap().entrySet())
			{
				returnValue.put(entry.getKey(), entry.getValue());
			}
		}
		// List<Field> fields=xmlPage.getFields();
		handleXmlFields(fields, content, pageResult, returnValue);
		
		
	}
	
	/**
	 *  将挖掘的链接入队,此CrawlUrl里有关联信息
	 * @param content
	 * @param pageResult
	 * @param returnValue
	 * @param xmlPage
	 * @param acceptDecideRuleHandler
	 */
	private void handleLinkPage(String content, PageResult pageResult,Map<String,Object> returnValue,Page xmlPage,AcceptDecideRuleHandler acceptDecideRuleHandler){
		

		 if(xmlPage.getLinkPages()!=null)
		 {
			 for(LinkPage linkPage:xmlPage.getLinkPages()){
				 Map<String,Object> linkParamValueMap=new HashMap<String, Object>();
				 if(linkPage.getParams()!=null)  //将本page的设定需填入的值赋入
				 {
					 for(Param param:linkPage.getParams())
					 {
						 linkParamValueMap.put(param.getName(),FillParamValueUtil.fillParamValue("", param.getValue(), returnValue));
					 }
				 }
				 

				 Set<String> linksUrlSet=new HashSet<String>();
				 if(linkPage.getDigLinks()!=null)
				 {
					 putParseDigLink(linkPage.getDigLinks(), linksUrlSet, acceptDecideRuleHandler, content,returnValue);
				 }
				 Set<CrawlUrl> digUrlSet=CrawlUrlUtil.getCrawlUrlSetByUrlSet(linksUrlSet,xmlTask.getScope());
				 for(CrawlUrl crawlUrl:digUrlSet){
					 crawlUrl.setLinkParamValueMap(linkParamValueMap);
					 crawlUrl.setLinkPageName(linkPage.getName());
				 }
				 LinkPageInfo linkPageInfo=new LinkPageInfo();
				 //linkPageInfo.setLinkPageName(field.getLinkPage().getName());
				 linkPageInfo.setDigCrawlUrlSet(digUrlSet);
				 pageResult.setLinkPageInfo(linkPageInfo);
				 
				 
			 }
			
			 
		 }
		
	}
	
	
	/**
	 * 提取可抓取的链接
	 * @param xmlPage
	 * @param digUrlSet
	 * @param acceptDecideRuleHandler
	 * @param pageResult
	 */
	public void putParseDigLink(List<DigLink> digLinks,Set<String> digUrlSet, AcceptDecideRuleHandler acceptDecideRuleHandler,String content,Map valueMap){
		
		 if(digLinks!=null)
		 {
			 for(DigLink digLink :digLinks)
			 {
				List<String> digList=acceptDecideRuleHandler.handleRulesForDigLink(digLink.getRules(), content,valueMap);
				//digUrlSet.addAll(CrawlUrlUtil.getCrawlUrlSetByUrls(digList));
				digUrlSet.addAll(digList);
			 }
		 }
		
	}

	
	
	

	/**
	 * 处理解析出XmlFields的数据
	 * @param fields
	 * @param pageResult
	 * @param returnValue
	 */
	private void handleXmlFields(List<Field> fields,String content, PageResult pageResult,Map<String,Object> returnValue)
	{
		//String content=pageResult.getContent();
		 AcceptDecideRuleHandler acceptDecideRuleHandler=new AcceptDecideRuleHandler();
		 if(spiderController.getCustomLoadConfig().getCustomDecideRuleMap()!=null){ //自定义rule处理
			 acceptDecideRuleHandler.setCustomDecideRuleMap(spiderController.getCustomLoadConfig().getCustomDecideRuleMap());
		 }
		 for(Field field:fields)
		 {
			 List<Object> valList=acceptDecideRuleHandler.handleRulesForPersistent(field.getRules(), content,returnValue);
			 
			 handleFieldValue(  field,content, valList,pageResult,returnValue);
			 /*
			 if(field.getLinkPage()!=null)
			 {
				 Map<String,Object> linkParamValueMap=new HashMap<String, Object>();
				 if(field.getLinkPage().getParams()!=null)  //将本page的设定需填入的值赋入
				 {
					 for(Param param:field.getLinkPage().getParams())
					 {
						 linkParamValueMap.put(param.getName(),FillParamValueUtil.fillParamValue("", param.getValue(), returnValue));
					 }
				 }
				 

				 Set<String> linksUrlSet=new HashSet<String>();
				 if(field.getLinkPage().getDigLinks()!=null)
				 {
					 putParseDigLink(field.getLinkPage().getDigLinks(), linksUrlSet, acceptDecideRuleHandler, content,returnValue);
				 }
				 Set<CrawlUrl> digUrlSet=CrawlUrlUtil.getCrawlUrlSetByUrlSet(linksUrlSet,xmlTask.getScope());
				 for(CrawlUrl crawlUrl:digUrlSet){
					 crawlUrl.setLinkParamValueMap(linkParamValueMap);
					 crawlUrl.setLinkPageName(field.getLinkPage().getName());
				 }
				 LinkPageInfo linkPageInfo=new LinkPageInfo();
				 linkPageInfo.setLinkPageName(field.getLinkPage().getName());
				 linkPageInfo.setDigCrawlUrlSet(digUrlSet);
				 pageResult.setLinkPageInfo(linkPageInfo);
				 
			 }*/
		 }
		
	}
	
	/**
	 * 处理field中再包含field map集合 或 没有包含的情况
	 * @param fields
	 * @param valList
	 * @param itemMapReturnValue
	 */
	private void handleFieldValue( Field field,String content,List<Object> valList, PageResult pageResult,Map<String,Object> returnValue)
	{
		 if(field.getList()!=null) //有field子项集，则把当前作为一个list
		 {
		/*
			 if(field.getIsList()!=null&&1==field.getIsList())  //作为列表
			 {
				List<Map> itemList=new ArrayList<Map>();
				for(Object valOb:valList)
				{
					String val=(String)valOb;
					 Map<String,Object> itemMapReturnValue=new HashMap<String, Object>(); 
					 handleXmlFields( field.getFields(),val,pageResult,itemMapReturnValue); //递归
					 itemList.add(itemMapReturnValue);
				}
				 returnValue.put(field.getName(), itemList);
			 }else{
				 
				 
			 }
*/
			 List<Map> itemList = new ArrayList<Map>();
			 for(Object val:valList){
				 String con = StringUtil.toString(val);
				 Map<String,Object> itemMapReturnValue=new HashMap<String, Object>(); 
				 handleXmlFields( field.getList(),con,pageResult,itemMapReturnValue);
				 itemList.add(itemMapReturnValue);
			 }
			 
			 returnValue.put(field.getName(), itemList);

		 }else{  //没有子项
			 
			 putFieldValue( field,valList,returnValue);
		 }

		 
	}
	
	
	/**
	 * 将field解析出来的值放入returnValue map
	 * @param field
	 * @param valList
	 * @param returnValue
	 */
	private void putFieldValue(Field field,List<Object> valList,Map<String,Object> returnValue)
	{
		 if(field.getIsList()!=null&&1==field.getIsList())  //作为列表
		 {
	
			if(field.getJoinMark()!=null) //拼接成一个字符串
			{
				StringBuffer valBuf=new StringBuffer();
				for(int i=0;i<valList.size();i++)
				{
					String val=(String) valList.get(i);
					valBuf.append(val);
					if(i!=valList.size()-1)
					{
						valBuf.append(field.getJoinMark());
					}
					
				}
				returnValue.put(field.getName(), valBuf.toString());
			}else{ //列表
				returnValue.put(field.getName(), valList);
			}
		 }else{
			 if(valList!=null&&valList.size()>0)
			 {
				 returnValue.put(field.getName(), valList.get(0));
			 }
			
		 }
		
	}
	
}
